package services

import (
	"errors"
	"github.com/go-playground/validator/v10"
	"golang.org/x/crypto/bcrypt"
	"iris_product/common"
	"iris_product/datamodels"
	"iris_product/repositories"
	"strings"
)

type IUserService interface {
	AddUser(user *datamodels.User) (id int64,err error)
	IsLoginSuccess(userName string,password string) (user *datamodels.User,err error)
	ValidateUser(user *datamodels.User) (errStr string)
}

type UserService struct {
	repo repositories.IUser
}

func (u *UserService) AddUser(user *datamodels.User) (id int64, err error) {
	// 加密密码
	password, err := GeneratePassword(user.Password)
	if err != nil {
		return 0, err
	}
	user.Password = string(password)
	return u.repo.Insert(user)
}

// 验证密码
func (u *UserService) IsLoginSuccess(userName string, password string) (user *datamodels.User, err error) {
	user = &datamodels.User{}
	user, err = u.repo.Select(userName)
	if err != nil {
		return user, err
	}
	// 判断密码是否符合
	if !ValidatePassword(password,user.Password) {
		return nil,errors.New("密码错误")
	}
	return
}

// 验证结构体的信息
func (u *UserService) ValidateUser(user *datamodels.User) (errStr string) {
	validate := validator.New()
	err := validate.Struct(user)
	if err == nil {
		return ""
	}
	if _,isOk := err.(*validator.InvalidValidationError);isOk {
		return "验证解析错误"
	}
	if validationErrs,isOk := err.(*validator.ValidationErrors);isOk {
		for _,fieldError := range *validationErrs {
			errStr += fieldError.Error() + ""
		}
	}
	return strings.TrimSpace(errStr)
}

func NewUserService(repo repositories.IUser) IUserService {
	return &UserService{
		repo: repo,
	}

}

// 验证密码
func ValidatePassword(password, userPassword string) (isOk bool) {
	err :=  bcrypt.CompareHashAndPassword([]byte(userPassword),[]byte(password))
	if err != nil {
		common.Log.Debug("验证密码异常或密码不正确:" + err.Error())
		return false
	}
	return true
}

func GeneratePassword(userPassword string) ([]byte,error) {
	return bcrypt.GenerateFromPassword([]byte(userPassword),bcrypt.DefaultCost)
}